#pragma once
#include <string>

namespace std
{

#ifdef _UNICODE

	typedef wstring TString;
#	define ConsoleLog wprintf

#else

	typedef string TString;
#	define  ConsoleLog printf

#endif 

}

namespace Utils
{
	class StringUtils
	{
	public:

#ifdef _UNICODE
		template <typename T>
		static std::TString DigitToTString(const T& v)
		{
			return std::to_wstring(v);
		}

#else
		template <typename T>
		static std::TString DigitToTString(const T& v)
		{
			return std::to_string(v);
		}
#endif

		static int TStringToInt(const std::TString& str)
		{
			if (str.empty())
			{
				return 0;
			}
			return std::stoi(str);
		}

		static float TStringToFloat(const std::TString& str)
		{
			if (str.empty())
			{
				return 0.0f;
			}
			return std::stof(str);
		}

		static unsigned long TStringToULong(const std::TString& str)
		{
			if (str.empty())
			{
				return 0;
			}
			return std::stoul(str);
		}


		static unsigned int GenerateHashKey(const std::TString& Key)
		{
			unsigned int i = 0;
			size_t len = Key.length();
			while (len-- > 0) i = (i << 5) + i + Key[len];
			return i;
		}

		static std::string TStringToString(const std::TString& tstr)
		{
#ifdef _UNICODE
			return WStringToString(tstr);
#else
			return tstr;
#endif
		}

		static std::TString StringToTString(const std::string& str)
		{
#ifdef _UNICODE
			return StringToWString(str);
#else
			return str;
#endif
		}
		static std::string WStringToString(const std::wstring &ws)
		{
			size_t i;
			std::string curLocale = setlocale(LC_ALL, NULL);

			setlocale(LC_ALL, "chs");
			const wchar_t* _source = ws.c_str();
			size_t _dsize = 2 * ws.size() + 1;
			char* _dest = new char[_dsize];
			memset(_dest, 0x0, _dsize);

			wcstombs_s(&i, _dest, _dsize, _source, _dsize);

			std::string result = _dest;
			delete[] _dest;

			setlocale(LC_ALL, curLocale.c_str());
			return result;
		}

		static std::wstring StringToWString(const std::string &s)
		{
			size_t i;
			std::string curLocale = setlocale(LC_ALL, NULL);

			setlocale(LC_ALL, "chs");
			const char* _source = s.c_str();
			size_t _dsize = s.size() + 1;
			wchar_t* _dest = new wchar_t[_dsize];
			wmemset(_dest, 0x0, _dsize);

			mbstowcs_s(&i, _dest, _dsize, _source, _dsize);

			std::wstring result = _dest;
			delete[] _dest;

			setlocale(LC_ALL, curLocale.c_str());
			return result;
		}


	};
}